#include "../pdb_index/aa.h"
#include "../pdb_index/atom.h"

#define NEIGHBORS 5

/**
   A representation of the neighborhood surrounding an amino acid.
 */
struct aa_bond_neighborhood {
  char structure[4];
  struct aa center;
  struct aa neighbors[NEIGHBORS];
  struct atom backBoneCarbon;
};


/**
   When calculating neighborhood distances, the weight to be given to
   the distance between the actual location of the amino acid.
*/
#define AA_POS_WEIGHT  1.000

/**
   When calculating neighborhood distances, the weight to be given to
   the difference in residue orientation.  (Euclidian distance between
   the direction vectors of the two amino acids.)

   The dir vectors tend to be rather small, (1-2 angstroms), so this
   weight is set a bit higher than the position.  Otherwise,
   orientation would be 'drowned out' by the position vectors.

*/
#define AA_DIR_WEIGHT  3.000

/**
   When calculating neighborhood distances, the weight to be given to
   differences in classes.  (The manhattan difference of the amino
   acids types' class bit vectors is multiplied by this weight.)

   This is a kludge, as all classes are treated equally. (even
   redundant ones, like small, medium, and large) We really should
   have a 22x22 symmetric distance matrix, and do lookups at runtime,
   but then we'd need to have a strong rationale behind the weights.

*/
#define AA_CLASS_WEIGHT 3.000

/** 
   This calculates a distance metric between two amino acids.  It
   uses position, orientation, and amino acid type.
*/
double aa_distance(struct aa* aa1, struct aa* aa2);

void aa_bond_neighborhood_init(struct aa_bond_neighborhood * neigh, char structure[4], struct aa * center, struct atom * carbon, struct aa neighbors[]);
void aa_bond_neighborhood_print(struct aa_bond_neighborhood * neigh);
void aa_bond_neighborhood_TranslateAndRotate(struct aa_bond_neighborhood * n);
double aa_bond_neighborhood_distance(struct aa_bond_neighborhood * n1, struct aa_bond_neighborhood * n2);
